﻿namespace WingBeats.CSS.AST

open WingBeats.CSS.Values

type private property  = string
and  private selector  = string
and  private key       = string
and  private reference = string

and DeclarationValue =
    | Reference    of reference
    | StringValue  of string * (key * (string -> string)) option
    | FloatValue   of float  * (key * (float  -> string)) option
    | IntegerValue of int    * (key * (int    -> string)) option
    | ColorValue   of Color  * (key * (Color  -> string)) option
    
    member this.GetValue variables =
        let rec getValue dv =
            let getStr v func = match func with | Some (_, f) -> f v
                                                | None     -> v.ToString()
            match dv with
            | StringValue  (str, f)  -> getStr str f
            | FloatValue   (fl , f)  -> getStr fl  f
            | IntegerValue (i  , f)  -> getStr i   f
            | ColorValue   (c  , f)  -> getStr c   f
            | Reference    (reference) 
                -> variables 
                   |> List.rev
                   |> List.find (function | KeyValue (key, _)
                                            -> key = reference)
                   |> (function | KeyValue (_, value) -> value |> getValue)
        getValue this

and DomainItem =
    | Declaration       of property * DeclarationValue
    | Collection        of DomainItem list
    | DomainItemCreator of key * obj * (obj -> DomainItem)

    member this.GetValue () = match this with
                              | Declaration _ -> this
                              | Collection  _ -> this
                              | DomainItemCreator (_, obj, creator)
                                -> creator obj        

and Combinator =
    | Child
    | Descendant
    | DirectAdjacent
    | IndirectAdjacent

and domain =
    | Domain   of selector * (DomainItem list) * (domain list)
    
and keyValue =
    | KeyValue of key * DeclarationValue

type stylesheet = 
    | Stylesheet of keyValue list * domain list

    member this.KeyValues = match this with
                            | Stylesheet (keyValues, _) -> keyValues
    member this.Domains = match this with
                          | Stylesheet (_, domains) -> domains